import { BehaviorNode } from "./BehaviorNode";
import { AServiceNode } from "./ServiceNode";
import { ATaskNode } from "./TaskNode";
import { BT_Oper, IBTCompositeChild, IBTDecoratorLogic, IOperationStackInfo } from "./types";

export abstract class CompositeNode<T  extends IGameEntity> extends BehaviorNode<T>
{
    protected _children:IBTCompositeChild<T>[]=[];
    protected _services:AServiceNode<T>[]=[];
    constructor(children?:IBTCompositeChild<T>[])
    {
        super();
        if(children)
        {
            this._children = children;
        }
        else
        {
            this._children=[];
        }
    }
    /**
     * 执行
     * */ 
    public execute(SearchData:IBehaviorTreeSearchData<T>): BT_BEHAVIOR_CODE 
    {
        let code=this.findChildToExecute(SearchData,BT_SUCCESSED);
        while(code.index !== BT_ReturnToParent)
        {
            code=this.findChildToExecute(SearchData,BT_SUCCESSED);
            if(code.lastResult == BT_ABORTED)
            {
                // 终止
            }
        }
        return code.lastResult;
    }
    public addChild(child:IBTCompositeChild<T>)
    {
        this._children.push(child);
    }
    protected getChild(index:number)
    {
        return this._children[index];
    }
    protected getChildrenNum()
    {
        return this._children.length;
    }
    protected findChildToExecute(SearchData:IBehaviorTreeSearchData<T> ,LastResult:BT_BEHAVIOR_CODE):ICompositeReturn
    {
        let ret_idx:number = BT_ReturnToParent;
        const  NodeMemory = this.getNodeMemory<IBTCompositeMemory>(SearchData);
        if(this._children.length)
        {
            let childindex = this.getNextChild(SearchData,NodeMemory.currentChild,LastResult);
 
            while(this._children.length>childindex)
            {
                if(this.doDecoratorsAllowExecution(SearchData,0,childindex))
                {
                    LastResult = this.onExecuteChild(SearchData,childindex);
                    ret_idx =childindex;
                    break;
                }
                else
                {
                    LastResult = BT_FAILED;

                }
                childindex = this.getNextChild(SearchData,childindex,LastResult);
            }
        }
        return {lastResult:LastResult,index:ret_idx}
    }
	private onExecuteChild(SearchData:IBehaviorTreeSearchData<T> ,  childIdx:number)
    {
        const childinfo = this.getChild(childIdx);
        if(childinfo.ConpositeChild)
        {
            return childinfo.ConpositeChild.execute(SearchData);
        }
        else   if(childinfo.TaskChild)
        {
            return childinfo.TaskChild.executeTask(SearchData.owner)
        }
        throw new Error(`没有child节点`);
    }
    protected getNextChild(SearchData:IBehaviorTreeSearchData<T> ,  LastChildIdx:number,LastResult:BT_BEHAVIOR_CODE):number
    {
        return this.getNextChildHandler(SearchData,LastChildIdx,LastResult);
    }
    protected abstract  getNextChildHandler(SearchData:IBehaviorTreeSearchData<T>, LastChildIdx:number ,LastResult:BT_BEHAVIOR_CODE):number
 

    private doDecoratorsAllowExecution(SearchData:IBehaviorTreeSearchData<T>, instanceIndex:number,childIndex:number):boolean
    {
        let  bResult = true;
        const 	  ChildInfo:IBTCompositeChild<T> = this._children[childIndex];

        if(ChildInfo.Decorators.length==0)
        {
            return true;
        }
        for (let DecoratorIndex = 0; DecoratorIndex < ChildInfo.Decorators.length; DecoratorIndex++)
        {
            const TestDecorator = ChildInfo.Decorators[DecoratorIndex];
            const   bIsAllowed = TestDecorator ? TestDecorator.canExecute(SearchData.owner) : false;

            const  ChildNode = this.getChild(childIndex);

            if (!bIsAllowed)
            {
                bResult = false;
                break;
            }
            else
            {
            }
        }
        return bResult
    }
}
 